package org.jeecg.activiti.controller;

import java.util.List;
import javax.annotation.Resource;

import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.ProcessInstanceMeta;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.apache.shiro.SecurityUtils;
import org.jeecg.activiti.entity.FlowInfo;
import org.jeecg.activiti.entity.ProcessParams;
import org.jeecg.activiti.service.IFlowInfoService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/bpm")
@Api(tags = "工作流")
public class ProcessInstanceController {

	@Resource(name = "jeecgActivitiProcessRuntime")
	private ProcessRuntime processRuntime;

	@Autowired
	private IFlowInfoService iFlowInfoService;

	@GetMapping("/processInstances")
	@ApiOperation(value = "获取取流程实例列表", notes = "获取所有取流程实例列表")
	public Result<List<ProcessInstance>> getProcessInstances() {
		Result<List<ProcessInstance>> r = new Result<List<ProcessInstance>>();

		List<ProcessInstance> processInstances = processRuntime.processInstances(Pageable.of(0, 10)).getContent();

		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setResult(processInstances);
		return r;
	}

	@GetMapping("/processInstanceMeta")
	@ApiOperation(value = "根据ID获取流程实例", notes = "根据ID获取流程实例")
	public Result<ProcessInstanceMeta> getProcessInstanceMeta(
			@RequestParam(value = "processInstanceId") String processInstanceId) {
		Result<ProcessInstanceMeta> r = new Result<ProcessInstanceMeta>();

		ProcessInstanceMeta processInstanceMeta = processRuntime.processInstanceMeta(processInstanceId);

		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setResult(processInstanceMeta);
		return r;
	}

	/**
	 * 流程部署
	 */
	@AutoLog(value = "部署流程-根据ID部署流程")
	@RequestMapping(value = "/deployFlow", method = RequestMethod.POST)
	@ApiOperation(value = "部署流程", notes = "根据ID部署流程")
	public Result<FlowInfo> deployFlow(@RequestParam(value = "flowId") String flowId) {

		FlowInfo flow = iFlowInfoService.getById(flowId);

		// 检测人员
		// LoginUser user =
		// (LoginUser)SecurityUtils.getSubject().getPrincipal();
		// 1.获取processEngine
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		// 2.获取repositoryService对象
		RepositoryService repositoryService = processEngine.getRepositoryService();
		// 3.部署
		Deployment deploy = repositoryService.createDeployment().addClasspathResource(flow.getFilePath())
				.name(flow.getFlowName()).deploy();
		log.info("流程部署id:" + deploy.getId());
		log.info("流程部署名称:" + deploy.getName());
		flow.setDeployId(deploy.getId());
		flow.setDeployName(deploy.getName());
		flow.setDeployVersion(flow.getVersion());
		boolean b = iFlowInfoService.saveOrUpdate(flow);
		Result<FlowInfo> r = new Result<FlowInfo>();
		if (b) {

			r.setSuccess(true);
			r.setCode(CommonConstant.SC_OK_200);
			r.setResult(flow);
		} else {
			r.setSuccess(false);
			r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
		}

		return r;
	}

	/**
	 * 流程启动
	 */
	@AutoLog(value = "流程启动")
	@RequestMapping(value = "/start", method = RequestMethod.POST)
	@ApiOperation(value = "流程启动", notes = "流程启动")
	public Result<ProcessParams> start(@RequestBody ProcessParams data) {
		// 1.获取processEngine
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		// 2.获取RunTimeService对象
		RuntimeService runtimeService = processEngine.getRuntimeService();
		// 3.流程定义的Key,流程图中的key myProcess_1
		String key = data.getProcessDefinitionKey();
		//org.activiti.engine.runtime.ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,"202004090936", map);
		org.activiti.engine.runtime.ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, data.getParameter());
		log.info(processInstance.getName());
		log.info(processInstance.getProcessInstanceId());
		data.setProcessInstanceId(processInstance.getProcessInstanceId());
		
		Result<ProcessParams> r = new Result<ProcessParams>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setResult(data);
		return r;
	}

	/**
	 * 流程完成
	 */
	@AutoLog(value = "执行流程")
	@RequestMapping(value = "/complete", method = RequestMethod.POST)
	@ApiOperation(value = "执行流程", notes = "执行流程")
	public Result<ProcessParams> complete(@RequestBody ProcessParams data) {
		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		// 1.获取processEngine
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		// 2.获取TaskService对象
		TaskService taskService = processEngine.getTaskService();
		// 3.查询当前用户是否有任务
		String key = data.getProcessInstanceId();
		Task task = taskService.createTaskQuery().processInstanceId(key).taskAssignee(user.getUsername())
				.singleResult();
		
		Result<ProcessParams> r = new Result<ProcessParams>();
		// 4.判断task !=null 说明当前有任务
		if (task != null) {
			taskService.complete(task.getId());
			log.info("任务执行完成");
			r.setSuccess(true);
			r.setCode(CommonConstant.SC_OK_200);
			r.setMessage("任务执行完成");
		}else{
			r.setSuccess(false);
			r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
			r.setMessage("流程不存在");
		}
		return r;
	}
}
